package com.basker.pisces.utils;

import org.springframework.util.Assert;

import com.basker.pisces.exception.ExceptionFactory;

public class EnumUtils {

    /**
     * 获取位枚举的整型值
     *
     * @param enums
     * @return
     */
    public static <T extends Enum<T>> int getFlagEnumsValue(T[] enums) {
        if (enums == null) {
            return 0;
        }

        int value = 0;

        for (T e : enums) {
            int flag = 1 << e.ordinal();
            value |= flag;
        }

        return value;
    }

    public static boolean isEnumObject(Object object) {
        Assert.notNull(object, "parameter 'object' is required");
        return object.getClass().isEnum();
    }

    /**
     * 判断位枚举整型值中是否包含指定枚举
     *
     * @param flagsValue
     * @param flagEnum
     * @return
     */
    public static <T extends Enum<T>> boolean isMatchEnum(int flagsValue, T flagEnum) {
        int flag = 1 << flagEnum.ordinal();
        return (flagsValue & flag) == flag;
    }

    /**
     * 判断枚举集合中是否包含指定枚举
     *
     * @param enums
     * @param flagEnum
     * @return
     */
    public static <T extends Enum<T>> boolean isMatchEnum(T[] enums, T flagEnum) {
        int flagsValue = EnumUtils.getFlagEnumsValue(enums);
        return isMatchEnum(flagsValue, flagEnum);
    }

    /**
     * 整数转换枚举
     *
     * @param enumType
     * @param enumOrdinal
     * @return
     */
    public static <T extends Enum<T>> T parse(Class<T> enumType, int enumOrdinal) {
        T[] enumConstants = enumType.getEnumConstants();
        if (enumOrdinal > 0 && enumOrdinal < enumConstants.length) {
            return enumConstants[enumOrdinal];
        }

        throw new IllegalArgumentException("No enum ordinal " + enumOrdinal + " for " + enumType.getCanonicalName());
    }

    /**
     * 字符砖转换枚举
     *
     * @param enumType
     * @param enumStringValue
     * @return
     */
    public static <T extends Enum<T>> T parse(Class<T> enumType, String enumStringValue) {
        try {
            return Enum.valueOf(enumType, enumStringValue);
        } catch (Exception e) {
            throw ExceptionFactory.createRuntimeException(e);
        }
    }

}
